/*
 * Copyright © ${year} ${owner} (${email})
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.jd.live.agent.implement.service.config.apollo;

import com.jd.live.agent.core.extension.annotation.ConditionalOnProperty;
import com.jd.live.agent.core.extension.annotation.Extension;
import com.jd.live.agent.core.inject.annotation.Injectable;
import com.jd.live.agent.core.util.Close;
import com.jd.live.agent.governance.annotation.ConditionalOnConfigCenterEnabled;
import com.jd.live.agent.governance.service.config.AbstractConfigService;
import com.jd.live.agent.governance.service.config.ConfigSubscription;
import com.jd.live.agent.governance.subscription.config.ConfigName;
import com.jd.live.agent.governance.subscription.config.Configurator;
import com.jd.live.agent.implement.service.config.apollo.client.ApolloClientApi;
import com.jd.live.agent.implement.service.config.apollo.client.ApolloClientFactory;
import com.jd.live.agent.implement.service.config.apollo.client.ApolloProperties;

import java.util.List;
import java.util.Map;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ConcurrentHashMap;

@Injectable
@ConditionalOnConfigCenterEnabled
@ConditionalOnProperty(name = "agent.governance.configCenter.type", value = "apollo")
@Extension("ApolloConfigService")
public class ApolloConfigService extends AbstractConfigService<ApolloClientApi> {

    protected final Map<String, ApolloClientApi> clients = new ConcurrentHashMap<>();

    @Override
    protected ConfigSubscription<ApolloClientApi> createSubscription(ConfigName configName) throws Exception {
        ApolloClientApi client = clients.computeIfAbsent(configName.getName(),
                name -> ApolloClientFactory.create(new ApolloProperties(governanceConfig.getConfigCenterConfig(), configName)));
        client.connect();
        return new ConfigSubscription<>(client, configName, getParser(configName));
    }

    @Override
    protected CompletableFuture<Void> doStop() {
        clients.forEach((namespace, client) -> Close.instance().close(client));
        clients.clear();
        return CompletableFuture.completedFuture(null);
    }

    @Override
    protected Configurator createConfigurator(List<ConfigSubscription<ApolloClientApi>> subscriptions) {
        return new ApolloConfigurator(subscriptions);
    }

}
